package com.example.gifdemo;

import java.util.List;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.BitmapDrawable;
import android.os.AsyncTask;
import android.os.Handler;
import android.util.Log;

import com.example.gifdemo.GifDecoder.GifFrame;

/**
 * 
 * @author cainli   2013-1-31  下午4:42:55
 *
 */
public class GifDrawable extends AnimationDrawable implements GifDecoder.DecoderCallBack{
	private static final String TAG = GifDrawable.class.getSimpleName();
	public static final int ASYNC_DECODE = 0x01;
	public static final int SYNC_DECODE = 0x02;
	private int decodeType = SYNC_DECODE;
	private Context context;
	private boolean hadDecoded = false;
	private boolean hadStarted = false;
	private int delay = -1;
	private Handler handler = new Handler();
	private String path;

	public GifDrawable(Context context) {
		super();
		this.context = context;
		init();
	}
	private void init() {
		setOneShot(false);
	}
	
	/**
	 * {@link ASYNC_DECODE},{@link SYNC_DECODE},
	 * default is {@link SYNC_DECODE},
	 * @param decodeType
	 */
	public void setDecodeType(int decodeType){
		this.decodeType = decodeType;
	}
	
	
	public void setPath(String path) {
		this.path = path;
	}
	/**
	 * 解码
	 */
	private void decode() {
		hadDecoded = true;
		if(path == null || "".equals(path)){
			return ;
		}
		new AsyncTask<Void, Void, List<GifFrame>>() {
			@Override
			protected List<GifFrame> doInBackground(Void... params) {
				GifDecoder d = new GifDecoder();
				switch (decodeType) {
					case ASYNC_DECODE:
						d.setCallBack(GifDrawable.this);
						try {
							d.read(path);
						} catch (Exception e) {
							Log.e(TAG, e.getMessage());
						}
						break;
					case SYNC_DECODE:
						try {
							d.read(path);
						} catch (Exception e) {
							Log.e(TAG, e.getMessage());
						}
						break;
					default:
						break;
				}
				return d.getFrames();
			}
			@Override
			protected void onPostExecute(List<GifFrame> result) {
				if(	result!=null && getNumberOfFrames() < result.size()){
					for(GifFrame frame: result){
						addFrame(new BitmapDrawable(context.getResources(),frame.image), frame.delay);
					}
				}
				start();
			};

		}.execute();
	}
	
	@Override
	public void draw(Canvas canvas) {
		super.draw(canvas);
		if(!hadDecoded){
			decode();
		}
	}

	@Override
	public void onGetOneFrame(final GifFrame frame, int index,long nextFrameTime) {
		//此方法在非UI线程
		Runnable runnable = new Runnable() {
			@Override
			public void run() {
				addFrame(new BitmapDrawable(context.getResources(),frame.image), frame.delay);
				start();
			}
		};
		if(delay == -1){ //第一帧
			handler.post(runnable);
		}else{
			long now = android.os.SystemClock.uptimeMillis();
			if (now < nextFrameTime) {
				handler.postDelayed(this, nextFrameTime - now);
			}
			else {
				handler.post(runnable);
			}
		}
	}
	
	@Override
	public void start() {
		if(!hadStarted){
			super.start();
			hadStarted = true;
		}
	}
}
